package com.ziq.zcamp.post

import android.widget.Toast
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.blankj.utilcode.util.NetworkUtils
import com.gmlive.camp.data.exception.LocalException
import com.ziq.base.extension.launchWithTryAsynchronous
import com.ziq.zcamp.R
import com.ziq.zcamp.api.request.post.*
import com.ziq.zcamp.api.respond.CampBaseRespond
import com.ziq.zcamp.api.respond.post.MoreCommentReplyRespond
import com.ziq.zcamp.api.respond.post.PostingCommentCreateRespond
import com.ziq.zcamp.api.respond.post.PostingCommentListRespond
import com.ziq.zcamp.api.respond.post.PostingCommentReplyRespond
import com.ziq.zcamp.api.service.NetWorkException
import com.ziq.zcamp.api.service.PostingService
import com.ziq.zcamp.api.service.ServiceModule.Companion.onApiFail
import com.ziq.zcamp.api.service.request
import com.ziq.zcamp.bean.post.CommentItem
import com.ziq.zcamp.bean.post.ReplyCommentItem
import com.ziq.zcamp.manager.GlobalContextManager
import com.ziq.zcamp.manager.UserManager
import com.ziq.zcamp.view.StatusView
import com.ziq.zcamp.view.StatusViewData
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import javax.inject.Inject

@HiltViewModel
class CommentViewModel @Inject constructor() : ViewModel() {

    @Inject
    lateinit var mPostingService: PostingService
    
    private var commentPage = 1
    var commentLastId = ""
    //通过评论中心跳转过来的
    var targetCommentItem : CommentItem? = null
    //comment数据
    val commentData = MutableLiveData<MutableList<CommentItem>?>()

    val allCommentListDialogStatusShow = MutableLiveData<StatusViewData>()
    val commentListRequestFinished = MutableLiveData<Boolean>()
    val commentListHasMore = MutableLiveData<Boolean>()
    //发评论 滚到第一条
    val commentListScrollToPosition = MutableLiveData<Int>()
    val currentInput = MutableLiveData<String>()
    val commentCount = MutableLiveData<Int>()
    val likeStatus = MutableLiveData<UserManager.PostingLikeStatus>()

    var create_uid: Int = 0
    var postId : String = ""

    fun initData(create_uid: Int, postId : String){
        this.create_uid = create_uid
        this.postId = postId
    }

    fun onRefreshComment(){
        commentPage = 1
        commentLastId = ""
        requestComment(create_uid, postId)
    }

    fun onLoadMoreComment(){
        requestComment(create_uid, postId)
    }

    private fun requestComment(create_uid: Int, postId : String,
        onSuccess: ((result: PostingCommentListRespond) -> Unit)? = {
            commentListRequestFinished.postValue(true)
            if (it.data != null){
                val tempList = mutableListOf<CommentItem>()
                //要跳转的评论显示第一位
                if(targetCommentItem != null){
                    tempList.add(targetCommentItem!!)
                }

                if(commentPage != 1 && commentData.value != null){
                    for (item in commentData.value!!){
                        if(!tempList.contains(item)){
                            tempList.add(item)
                        }
                    }
                }

                if(it.data!!.comments?.isNotEmpty() == true){
                    for (item in it.data!!.comments!!){
                        item.user_info?.parseData()
                        if(targetCommentItem != null && targetCommentItem?.equals(item) == true){
                            targetCommentItem?.has_more = item.has_more
                            targetCommentItem?.content = item.content
                            if(targetCommentItem?.reply_content == null){
                                targetCommentItem?.reply_content = mutableListOf()
                            }
                            if(item.reply_content != null){
                                for (reply in item.reply_content!!){
                                    if(!targetCommentItem?.reply_content!!.contains(reply)){
                                        targetCommentItem?.reply_content?.add(reply)
                                    }
                                }
                            }
                        } else if(!tempList.contains(item)){
                            tempList.add(item)
                        }
                    }
                }

                commentData.postValue(tempList)
                commentPage++
                commentLastId = it.data!!.cursor?:""
                commentListHasMore.postValue(it.data!!.has_more)
            } else {
                commentListHasMore.postValue(false)
            }

        },
        onFail: ((result: String) -> Unit)? = {
            commentListRequestFinished.postValue(true)
            if(commentPage == 1){
                commentData.postValue(null)
            }
            if(NetworkUtils.isConnected()){
                onApiFail(it)
            }
        }) {
        launchWithTryAsynchronous(whenTry = {

            val respond = mPostingService.commentPage(CommentPageParam().apply {
                this.create_uid = create_uid
                this.post_id = postId
                this.start = commentPage
                this.count = 20
                this.id = commentLastId
            }.queryMap).request()

            withContext(Dispatchers.Main){
                onSuccess?.invoke(respond)
            }
        }, whenCatch = {
            withContext(Dispatchers.Main){
                when(it){
                    is NetWorkException -> {
                        onFail?.invoke(it.errorMsg)
                    }
                    else -> {
                        onFail?.invoke("数据错误,请重试")
                    }
                }
            }
        })
    }

    fun sendComment(post_id: String, post_uid: Int, content: String,
        onSuccess: ((result: PostingCommentCreateRespond) -> Unit)? = {
            if(it.data != null){
                it.data?.user_info?.parseData()

                val tempList = mutableListOf<CommentItem>()
                if(commentData.value != null){
                    tempList.addAll(commentData.value!!)
                }
                tempList.add(0, it.data!!)
                commentData.postValue(tempList)
                commentListScrollToPosition.postValue(0)
                commentCount.postValue((commentCount.value?:0) + 1)

                val msg = GlobalContextManager.getString(R.string.send_comment_success)
                Toast.makeText(GlobalContextManager.appContext!!, msg, Toast.LENGTH_SHORT).show()
            } else {
                val errMsg = GlobalContextManager.getString(R.string.send_comment_fail)
                Toast.makeText(GlobalContextManager.appContext!!, errMsg, Toast.LENGTH_SHORT).show()
            }
        },
        onFail: ((str:String,errorCode : Int) -> Unit)? = { str,code ->
            onApiFail(str)
        }) {
        launchWithTryAsynchronous(whenTry = {

            val respond = mPostingService.commentCreate(CommentCreateParam().apply {
                this.post_id = post_id
                this.post_uid = post_uid
                this.content = content
            }).request()

            withContext(Dispatchers.Main){
                onSuccess?.invoke(respond)
            }
        }, whenCatch = {
            withContext(Dispatchers.Main){
                when(it){
                    is NetWorkException -> {
                        onFail?.invoke(it.errorMsg,it.errorCode)
                    }
                    is LocalException -> {
                        onFail?.invoke("数据错误,请重试",it.errorCode)
                    }
                    else ->{
                        onFail?.invoke("数据错误,请重试",-1)
                    }
                }
            }
        })
    }

    fun replyComment(post_id: String, post_uid: Int, content: String, position:Int?, commentItem: CommentItem? = null, replyCommentItem: ReplyCommentItem? = null,
                     onSuccess: ((result: PostingCommentReplyRespond) -> Unit)? = {
                        if(it.data != null){
                            if(commentItem != null){
                                if(commentItem.reply_content == null){
                                    commentItem.reply_content = mutableListOf()
                                }
                                if(it.data!!.reply_content?.get(0) != null){
                                    commentItem.reply_content!!.add(0, it.data!!.reply_content?.get(0)!!)
                                }
                            } else if(replyCommentItem != null){
                                if(replyCommentItem.parent?.reply_content == null){
                                    replyCommentItem.parent?.reply_content = mutableListOf()
                                }
                                if(it.data!!.reply_content?.get(0) != null){
//                                    val index = replyCommentItem.parent?.reply_content?.indexOf(replyCommentItem)
//                                    if (index != null && index >= 0) {
//                                        replyCommentItem.parent?.reply_content!!.add(index + 1, it.data!!.reply_content?.get(0)!!)
//                                    }else {
//                                        replyCommentItem.parent?.reply_content!!.add(0, it.data!!.reply_content?.get(0)!!)
//                                    }
                                    replyCommentItem.parent?.reply_content!!.add(0, it.data!!.reply_content?.get(0)!!)
                                }
                            }
                            commentData.postValue(commentData.value)
                            commentCount.postValue((commentCount.value?:0) + 1)

//                            if(position != null){
//                                commentListScrollToPosition.postValue(position)
//                            }

                            val msg = GlobalContextManager.getString(R.string.reply_comment_success)
                            Toast.makeText(GlobalContextManager.appContext!!, msg, Toast.LENGTH_SHORT).show()
                        } else {
                            val errMsg = GlobalContextManager.getString(R.string.send_comment_fail)
                            Toast.makeText(GlobalContextManager.appContext!!, errMsg, Toast.LENGTH_SHORT).show()
                        }
                    },
                     onFail: ((result: String,code : Int) -> Unit)? = { str , code ->
                        onApiFail(str)
                    }) {

        launchWithTryAsynchronous(whenTry = {

            val respond = mPostingService.commentReply(CommentReplyParam().apply {
                this.post_id = post_id
                this.post_uid = post_uid
                this.content = content
                if(commentItem != null){
                    this.comment_id = commentItem.comment_id
                    this.reply_uid = commentItem.user_info?.uid
                } else if(replyCommentItem != null){
                    this.comment_id = replyCommentItem.parent?.comment_id
                    this.reply_comment_father_id = replyCommentItem.reply_comment_id
                    this.reply_uid = replyCommentItem.reply_info?.uid
                }
            }).request()

            withContext(Dispatchers.Main){
                onSuccess?.invoke(respond)
            }
        }, whenCatch = {
            withContext(Dispatchers.Main){
                when(it){
                    is NetWorkException -> {
                        onFail?.invoke(it.errorMsg,it.errorCode)
                    }
                    is LocalException -> {
                        onFail?.invoke("数据异常，请重试",it.errorCode)
                    }
                    else -> {
                        onFail?.invoke("数据异常，请重试",-1)
                    }
                }
            }
        })
    }

    fun deleteComment(param: CommentDeleteParam,
                      onSuccess: ((result: CampBaseRespond) -> Unit)? = {},
                      onFail: ((result: String) -> Unit)? = {}) {
        launchWithTryAsynchronous(whenTry = {
            val respond = mPostingService.commentDelete(param).request()
            withContext(Dispatchers.Main){
                onSuccess?.invoke(respond)
            }
        }, whenCatch = {
            withContext(Dispatchers.Main){
                when(it){
                    is NetWorkException -> {
                        onApiFail(it.errorMsg)
                        onFail?.invoke(it.errorMsg)
                    }
                    else -> {
                        onApiFail("数据异常，请重试")
                        onFail?.invoke("数据异常，请重试")
                    }
                }
            }
        })
    }

    fun updateCommentLikeStatus(param:CommentLikeParam,
                    onSuccess: ((result: CampBaseRespond) -> Unit)? = {
                        commentData.postValue(commentData.value)
                    },
                    onFail: ((result: String) -> Unit)? = {}) {
        launchWithTryAsynchronous(whenTry = {
            val respond = mPostingService.commentLike(param).request()
            withContext(Dispatchers.Main){
                onSuccess?.invoke(respond)
            }
        }, whenCatch = {
            withContext(Dispatchers.Main){
                when(it){
                    is NetWorkException -> {
                        onApiFail(it.errorMsg)
                        onFail?.invoke(it.errorMsg)
                    }
                    else -> {
                        onApiFail("数据异常，请重试")
                        onFail?.invoke("数据异常，请重试")
                    }
                }
            }
        })
    }

    fun findMoreCommentReply(post_id: String?, item:CommentItem,
                                onSuccess: ((result: MoreCommentReplyRespond) -> Unit)? = {
                                    allCommentListDialogStatusShow.postValue(StatusViewData(
                                        StatusView.IDLE))
                                    if(it.data != null){
                                        item.has_more = it.data!!.has_more
                                        item.page++
                                        if(it.data?.reply_content?.isNotEmpty() == true){
                                            if(item.reply_content == null){
                                                item.reply_content = mutableListOf()
                                            }
                                            for (reply in it.data?.reply_content!!){
                                                if(!item.reply_content!!.contains(reply)){
                                                    item.reply_content?.add(reply)
                                                }
                                            }
                                        }
                                        commentData.postValue(commentData.value)
                                    }
                                },
                                onFail: ((result: String) -> Unit)? = {
                                    allCommentListDialogStatusShow.postValue(StatusViewData(StatusView.IDLE))
                                }) {
        launchWithTryAsynchronous(whenTry = {
            allCommentListDialogStatusShow.postValue(StatusViewData(StatusView.LOADING))

            val respond = mPostingService.moreCommentReply(MoreCommentReplyParam().apply {
                post_id?.let {
                    this.post_id = it
                }
                item.comment_id?.let {
                    this.comment_id = it
                }
                this.page = item.page
            }.queryMap).request()
            withContext(Dispatchers.Main){
                onSuccess?.invoke(respond)
            }
        }, whenCatch = {
            withContext(Dispatchers.Main){
                when(it){
                    is NetWorkException -> {
                        onApiFail(it.errorMsg)
                        onFail?.invoke(it.errorMsg)
                    }
                    else -> {
                        onApiFail("数据异常，请重试")
                        onFail?.invoke("数据异常，请重试")
                    }
                }
            }
        })
    }


}